
package com.ymx.sdk.widget.recyclerview;

import com.ymx.sdk.widget.recyclerview.viewholder.AbsViewHolder;
import com.ymx.sdk.widget.recyclerview.viewholder.HeaderFooterViewHolder;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.util.ArrayList;

public abstract class HFListRecyclerAdapter<T> extends ListRecyclerAdapter<T> {

    public ArrayList<View> mHeaderViews = new ArrayList<>();
    public ArrayList<View> mFooterViews = new ArrayList<>();
    public static final int VIEW_TYPE_HEADER = 0;
    public static final int VIEW_TYPE_FOOTER = 1;
    public static final int VIEW_TYPE_ITEM = 2;

    public HFListRecyclerAdapter(ArrayList<T> datas, Context context) {
        super(datas, context);
    }

    @Override
    public final int getItemViewType(int position) {
        if (isHeader(position)) {
            return VIEW_TYPE_HEADER;
        }
        else if (isFooter(position)) {
            return VIEW_TYPE_FOOTER;
        } else {
            return VIEW_TYPE_ITEM;
        }
    }

    @Override
    public final int getItemCount() {
        if (mList == null) mList = new ArrayList<>();
        return mHeaderViews.size() + mList.size() + mFooterViews.size();
    }

    @Override
    public AbsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (VIEW_TYPE_ITEM == viewType) {
            return getItemViewHoler(parent, viewType);
        } else {
            // create a new framelayout, or inflate from a resource
            FrameLayout frameLayout = new FrameLayout(parent.getContext());
            // make sure it fills the space
            frameLayout.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            return new HeaderFooterViewHolder(frameLayout, mContext);
        }
    }

    @Override
    public void onBindViewHolder(AbsViewHolder holder, int position) {
        // check what type of view our position is
        switch (getItemViewType(position))
        {
            case VIEW_TYPE_HEADER:
                View header = mHeaderViews.get(position);
                // add our view to a header view and display it
                if (holder instanceof HeaderFooterViewHolder) {
                    prepareHeaderFooter((HeaderFooterViewHolder) holder, header);
                }
                break;
            case VIEW_TYPE_FOOTER:
                View footer = mFooterViews.get(position - mList.size() - mHeaderViews.size());
                // add oru view to a footer view and display it
                if (holder instanceof HeaderFooterViewHolder) {
                    prepareHeaderFooter((HeaderFooterViewHolder) holder, footer);
                }
                break;
            case VIEW_TYPE_ITEM:
                super.onBindViewHolder(holder, position - mHeaderViews.size());
                break;
        }
    }

    private void prepareHeaderFooter(HeaderFooterViewHolder vh, View view) {
        // empty out our FrameLayout and replace with our header/footer
        vh.base.removeAllViews();
        // For The specified child already has a parent.
        // call removeView() on the child's parent first
        if (view != null) {
            ViewGroup parent = (ViewGroup) view.getParent();
            if (parent != null) {
                parent.removeView(view);
            }
        }

        vh.base.addView(view);
    }

    public void addHeaderView(@NonNull View headerView) {
        if (mHeaderViews != null) {
            if (!mHeaderViews.contains(headerView))
                mHeaderViews.add(0, headerView);
            notifyDataSetChanged();
            // notifyItemInserted(0);
        }
    }

    /**
     * add header view with position(use for after set adapter)
     * @param headerView
     * @param position
     */
    public void addHeaderView(@NonNull View headerView,int position) {
        if (mHeaderViews != null) {
            if (!mHeaderViews.contains(headerView))
                mHeaderViews.add(position, headerView);
            notifyDataSetChanged();
            // notifyItemInserted(0);
        }
    }

    public void addFooterView(@NonNull View footerView) {
        if (mFooterViews != null) {
            if (!mFooterViews.contains(footerView))
                mFooterViews.add(footerView);
            notifyDataSetChanged();
            // notifyItemInserted(mHeaderViews.size() + mList.size() +
            // mFooterViews.size() - 1);
        }
    }

    public void removeHeaderView(@NonNull View header) {
        if (mHeaderViews != null) {
            if (mHeaderViews.contains(header)) {
                notifyItemRemoved(mHeaderViews.indexOf(header));
                mHeaderViews.remove(header);
                if (header.getParent() != null) {
                    ((ViewGroup) header.getParent()).removeView(header);
                }
            }
        }
    }

    public void removeFooterView(@NonNull View footer) {
        if (mFooterViews != null) {
            if (mFooterViews.contains(footer)) {
                // animate
                notifyItemRemoved(mHeaderViews.size() + mList.size() + mFooterViews.indexOf(footer));
                mFooterViews.remove(footer);
                if (footer.getParent() != null) {
                    ((ViewGroup) footer.getParent()).removeView(footer);
                }
            }
        }
    }

    public boolean hasHeader() {
        if (mHeaderViews != null && mHeaderViews.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean hasFooter() {
        if (mFooterViews != null && mFooterViews.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isHeader(int position) {
        if (hasHeader() && position < mHeaderViews.size()) {
            return true;
        } else {
            return false;
        }

    }

    public boolean isFooter(int position) {
        if (hasFooter() && position >= mList.size() + (hasHeader() ? mHeaderViews.size() : 0)) {
            return true;
        } else {
            return false;
        }

    }

    public int getHeaderSize() {
        return mHeaderViews.size();
    }

    public int getFooterSize() {
        return mFooterViews.size();
    }

    public ArrayList<View> getHeaderViews() {
        return mHeaderViews;
    }

    public ArrayList<View> getFooterViews() {
        return mFooterViews;
    }

}
